package com.llbnk.controller;

import com.llbnk.dao.PromoDOMapper;
import com.llbnk.error.BusinessException;
import com.llbnk.log.LogAction;
import com.llbnk.log.LogGenerator;
import com.llbnk.logpool.LogPoolManager;
import com.llbnk.pojo.dto.ItemVO;
import com.llbnk.pojo.entity.DetailLog;
import com.llbnk.pojo.entity.PromoDO;
import com.llbnk.pojo.model.ItemModel;
import com.llbnk.response.CommonReturnType;
import com.llbnk.service.PromoService;
import com.llbnk.service.impl.ItemServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author shkstart
 * @create 2022-08-21 16:51
 */
@RestController
@CrossOrigin(allowCredentials = "true",allowedHeaders = "*")
@Slf4j
public class ItemController extends BaseController{

    //请求头Content-Type  application/x-www-form-urlencoded
    public static final String CONTENT_TYPE_FORMED="application/x-www-form-urlencoded";


    //异步更新日志
    @Resource
    private LogPoolManager logPoolManager;

    @Autowired
    private HttpServletRequest httpServletRequest;

    @Resource
    private ItemServiceImpl itemService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private PromoDOMapper promoDOMapper;

    @Resource
    private PromoService promoService;

    @GetMapping("/item/test")
    public String test(){
        PromoDO promoDO = promoDOMapper.selectByPrimaryKey(2);
        return promoDO.toString();
    }

    //商品创建
    @PostMapping(value = "/item/create", consumes = {CONTENT_TYPE_FORMED})
    public CommonReturnType createItem(@RequestParam(name = "title")String title,
                                       @RequestParam(name = "price") BigDecimal price,
                                       @RequestParam(name = "stock")Integer stock,
                                       @RequestParam(name = "description")String description,
                                       @RequestParam(name = "imgUrl")String imgUrl) throws BusinessException{
        ItemModel itemModel = new ItemModel();
        itemModel.setTitle(title);
        itemModel.setPrice(price);
        itemModel.setStock(stock);
        itemModel.setDescription(description);
        itemModel.setImgUrl(imgUrl);

        ItemModel itemModelForReturn = itemService.createItem(itemModel);

        ItemVO itemVO = convertFromModel(itemModelForReturn);
        log.info("intemVO ["+itemVO+"]");

        //插入异步日志
        userLog("manager", LogAction.INCREASE.getAction(),"增加新的活动");


        return CommonReturnType.create(itemVO);
    }

    private ItemVO convertFromModel(ItemModel itemModel){
        if(itemModel == null){
            return null;
        }
        ItemVO itemVO = new ItemVO();
        try {
            BeanUtils.copyProperties(itemModel, itemVO);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(itemModel.getPromoModel()!=null){
            //有正在或即将进行的活动
            itemVO.setPromoStatus(itemModel.getPromoModel().getStatus());
            itemVO.setPromoId(itemModel.getPromoModel().getId());
            itemVO.setStartDate(itemModel.getPromoModel().getStartDate()
                    .toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")));
            itemVO.setEndDate(itemModel.getPromoModel().getEndDate()
                    .toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")));
            itemVO.setPromoPrice(itemModel.getPromoModel().getPromoItemPrice());
        }else {
            itemVO.setPromoStatus(0);
        }

        return itemVO;
    }

    //商品页面浏览
    @GetMapping(value = "/item/list")
    public CommonReturnType listItem(){

        List<ItemModel> itemModelList = itemService.listItem();

        //使用stream api 将list内的 itemModel 转化为 itemVO
        List<ItemVO> itemVOList = itemModelList.stream().map(itemModel -> {
            ItemVO itemVO = convertFromModel(itemModel);
            return itemVO;
        }).collect(Collectors.toList());

        //插入异步日志
        userLog(null, LogAction.FIND.getAction(),"查看所有活动页面");


        return CommonReturnType.create(itemVOList);
    }

    //商品详情页浏览
    //使用redis缓存
    @GetMapping(value = "/item/getItem")
    public CommonReturnType getItem(@RequestParam("id") Integer id){
        ItemModel itemModel = (ItemModel) redisTemplate.opsForValue().get("item_"+id);
        if(itemModel ==  null){
            log.info("从数据库中拿出数据设置缓存");
            itemModel = itemService.getItemById(id);
            redisTemplate.opsForValue().set("item_"+id,itemModel);
            redisTemplate.expire("item_"+id,20, TimeUnit.SECONDS);
        }

        ItemVO itemVO = convertFromModel(itemModel);
        log.info("itemVO: "+itemVO);

        return CommonReturnType.create(itemVO);
    }

    /**
     * 用于负责在秒杀活动开始之前预先将库存呢信息放入redis中
     * @param id
     * @return
     */
    @RequestMapping(value = "/item/publishpromo",method = {RequestMethod.GET})
    @ResponseBody
    public CommonReturnType publishPromo(@RequestParam(name = "id")Integer id){
        promoService.publishPromo(id);
        return CommonReturnType.create(null);
    }

    /**专门用于插入异步日志的方法*/
    public void userLog(String userId,String action,String info){
        DetailLog DetailLog = new DetailLog();
        DetailLog.setLogcontent(LogGenerator.getLog(httpServletRequest,userId,action, info));
        // 将业务日志放入到队列中，然后使用线程 异步 批量进行入库，以提升接口的响应速度
        try {
            logPoolManager.addLog(DetailLog);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

}
